function [inputs, tables, moveScores, scaledScores, legalMoves] = ...
                formInputs(table, piece)

featureNum = 16;
legalMoves = getLegalMoves(piece);
moveNum = size(legalMoves, 2);
            
inputs = zeros(featureNum, moveNum);
tables = cell(moveNum, 1);
moveScores = zeros(moveNum, 1);
scaledScores = zeros(moveNum, 1);

[tableHeight, tableWidth] = size(table);

for move = 1 : moveNum
    [newTable, score, scaled_score, linesNum, weightedTable, tetrominoLand] = ...
            performMove(table, piece, legalMoves(1, move), legalMoves(2, move));
        
    tables{move} = newTable;
    moveScores(move) = score;
    scaledScores(move) = scaled_score;
    
    heightVector = max(weightedTable, [], 1);
    
    diffTable = diff(newTable);
    [iDiff, jDiff] = find(diffTable == -1);
    
    inputs(1, move) = max(heightVector);                                                % Pile Height
    inputs(2, move) = sum(heightVector - sum(newTable));                                % Holes
    inputs(3, move) = length(iDiff);                                                    % Connected Holes
    inputs(4, move) = linesNum;                                                         % Removed Lines
    inputs(5, move) = max(heightVector) - min(heightVector);                            % Altitude Difference
    [inputs(6, move), wells] = calcSumOfAllWells(heightVector);                         % Sum of all Wells
    inputs(7, move) = max(wells);                                                       % Maximum Well Depth
    inputs(8, move) = tetrominoLand;                                                    % Landing Height
    inputs(9, move) = sum(sum(newTable));                                               % Blocks
    inputs(10, move) = sum(sum(weightedTable));                                         % Weighted Blocks
    inputs(11, move) = calcRowTransitions(newTable);                                    % Row Transitions
    inputs(12, move) = calcColumnTransitions(newTable);                                 % Column Transitions
    [inputs(13, move), column] = calcHighestHole(iDiff, jDiff, tableHeight);            % Highest Hole
    inputs(14, move) = calcBlocksAboveHighestHole(newTable, inputs(13, move), ...       % Blocks Above Highest Hole
                                                        column);               
    inputs(15, move) = sum(sum(newTable(1 : end - inputs(13, move), :), 2) ...          % Potential Lines
                            > tableWidth - 2);                                          
    inputs(16, move) = calcSmoothness(heightVector, tableHeight);                       % Smoothness
end

scaledScores = 2 * scaledScores - max(scaledScores);
scaledScores(scaledScores < -1) = -1;



function [sumOfAllWells, wells] = calcSumOfAllWells(heightVector)

leftDiff = inf * ones(size(heightVector));
rightDiff = inf * ones(size(heightVector));

leftDiff(2 : end) = heightVector(1 : end - 1) - heightVector(2 : end);
rightDiff(1 : end - 1) = heightVector(2 : end) - heightVector(1 : end - 1);

wells = min(leftDiff, rightDiff);
wells(wells < 0) = 0;

sumOfAllWells = sum(wells);


function [ rowTransitions ] = calcRowTransitions( table )

rows = size(table, 1);

borderedTable = [ones(rows, 1), table, ones(rows, 1)];

diffMatrix = diff(borderedTable, 1, 2);

rowTransitions = sum(sum(diffMatrix == 1)) + sum(sum(diffMatrix == -1));


function [ colTransitions ] = calcColumnTransitions( table )

cols = size(table, 2);

borderedTable = [table; ones(1, cols)];

diffMatrix = diff(borderedTable);

colTransitions = sum(sum(diffMatrix == 1)) + sum(sum(diffMatrix == -1));


function [highestHole, column] = calcHighestHole(iDiff, jDiff, tableHeight)

if ~isempty(iDiff)
    iDiff = tableHeight - iDiff;
    [highestHole, maxIndex] = max(iDiff);
    column = jDiff(maxIndex);
else
    highestHole = 0;
    column = 0;
end


function [ blockCount ] = calcBlocksAboveHighestHole( table, highestHole, ...
                                                        highestHoleColumn )

blockCount = 0;
if highestHoleColumn ~= 0
    rows = size(table, 1);
    blockCount = sum(table(1:(rows - highestHole), highestHoleColumn));
end


function [ smoothness ] = calcSmoothness( columnHeights, tableHeight )

smoothness = sum(abs(diff(columnHeights))) + abs(tableHeight - ...
    columnHeights(1)) + abs(tableHeight - columnHeights(end));

  